package cn.edu.cuit.mockfns;

import java.util.List;

import cn.edu.cuit.mockfns.fam.Condition;
import cn.edu.cuit.mockfns.fam.FAMEngine;
import cn.edu.cuit.mockfns.fam.processors.Communicator;
import cn.edu.cuit.mockfns.fam.processors.EventListener;
import cn.edu.cuit.mockfns.fam.processors.EventSender;
import cn.edu.cuit.mockfns.fam.processors.InternalDefaultCommunicator;
import cn.edu.cuit.mockfns.fam.tuples.Event;
import cn.edu.cuit.mockfns.fam.tuples.State;

/**
 * famEngine seems like binding to this Class <strong>rather than the BusinessLogic object</strong>,
 * so, those fields in FAMEngine may should be declared carefully since that <strong>there maybe
 * something concurrent </strong>, e.g.<code> eventQueue</code> etc..
 * <p>
 * There needs more investigations of concurrency with <strong>the FAMEngine and it should be
 * designed more elaborately.</strong>
 * 
 * @see concurrency.ConcurrencyEntity
 * */
public abstract class BusinessLogic
{

    protected Object jobIdentity;
    private Communicator communicator;
    private EventListener listener;
    private EventSender sender;

    //    protected static FAMEngine famEngine;

    //Due to some technical programs, e.g. concurrency etc.. Now I choose following strategy:
    //Each business logic thread will has its own FAMEngine object.
    //Someday, I will refactor of it into two model(Time Efficiency module and Space Efficiency module )
    protected FAMEngine famEngine;
    protected Condition startCondition;
    protected List<BusinessResource> businessResources;
    

    public abstract void lauch();

    public abstract boolean canStart();

    public abstract void comsume( Event<?> event );

    /**
     * In normal case, when famEngine be in <code>CommonEndState</code>, <code>CommonStartState</code>, 
     * <code>CommonErrorState</code>, <code>CommonNoneState</code>, the <code>run</code> method will calls 
     * this method so that your own business logic implementation could get some useful informations e.t.
     * when here we are in <code>CommonErrorState</code>, you can investigate the transition history and 
     * figure the problem out etc..
     * */
    public abstract void respondSignal( State state );

    
    //This should be implemented to be Space Efficiency module
    //    static
    //    {
    //        famEngine = new FAMEngine();
    //
    //        //Have not been implemented
    //        famEngine.start();
    //    }

    public BusinessLogic(Object jobIdentity)
    {
        famEngine = new FAMEngine();
        this.jobIdentity = jobIdentity;
    }

    public BusinessLogic(FAMEngine famEngine, Condition statCondition, List<BusinessResource> businessResources)
    {

    }

    public void defaultLaunch()
    {
        Communicator communicator = InternalDefaultCommunicator.getInstanceForCurrentJob( (Integer) jobIdentity );
        while( true )
        {
            communicator.recieve();
        }
    }


    public List<BusinessResource> getBusinessResources()
    {
        return businessResources;
    }

    public void setBusinessResources( List<BusinessResource> businessResources )
    {
        this.businessResources = businessResources;
    }

    public FAMEngine famEngineInstance()
    {
        return famEngine;
    }

    public void setJobIdentity( Object jobId )
    {
        this.jobIdentity = jobId;
    }
}
